package com.bjy.qa.util.security;

import com.bjy.qa.dao.manage.RouteDao;
import com.bjy.qa.entity.manage.Route;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 自定义请求 URL 与配置属性之间的映射类（根据请求的 URL，查找适用于该 URL 的权限配置属性，比如角色,权限等信息）
 */
@Component
public class CustomFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {
    @Resource
    CustomFilterInvocationSecurityMetadataSourceMatcher customFilterInvocationSecurityMetadataSourceMatcher;

    @Resource
    RouteDao routeDao;

    public static List<MenuRole> menuRoleList; // 所有权限

    /**
     * 获取所有请求 url 的权限
     * @return
     */
    private List<MenuRole> getRoleMenu() {
        if (menuRoleList != null) {
            return menuRoleList;
        }
        menuRoleList = new ArrayList<>();

        List<Route> routeList = routeDao.getDirective();
        for (Route route : routeList) {
            // 判断是否已经存在
            MenuRole menuRole = null;
            for (MenuRole tmpMenuRole : menuRoleList) {
                if (tmpMenuRole.getUrl().equals(route.getMeta().getActiveMenu())) {
                    menuRole = tmpMenuRole;
                    break;
                }
            }

            if (menuRole == null) { // 没存在，新建
                menuRole = new MenuRole();
                menuRole.setUrl(route.getMeta().getActiveMenu()); // url 链接

                // 角色信息，以 | 包裹，这个链接哪些角色可以访问都写到一起
                StringBuffer sb = new StringBuffer();
                sb.append("|");
                for (String roleString : route.getMeta().getRoles()) {
                    sb.append(roleString);
                    sb.append("|");
                }
                menuRole.setRole(sb.toString());

                menuRoleList.add(menuRole); // 添加到权限列表
            } else { // 存在，添加对应角色
                StringBuffer sb = new StringBuffer();
                sb.append(menuRole.getRole());
                for (String roleString : route.getMeta().getRoles()) {
                    sb.append(roleString);
                    sb.append("|");
                }
                menuRole.setRole(sb.toString());
            }
        }
        return menuRoleList;
    }

    /**
     * 返回当前请求 URL 所需要的角色信息
     * @param object
     * @return
     * @throws IllegalArgumentException
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        getRoleMenu();
        String requestUrl = ((FilterInvocation) object).getRequest().getRequestURI();
        return SecurityConfig.createList(customFilterInvocationSecurityMetadataSourceMatcher.matcherUrlRole(requestUrl));
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return false;
    }
}